using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Ccr.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.ServiceModel.DsspServiceBase;
using W3C.Soap;
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using System.Drawing;
using System.Windows.Forms;
using Robotics.ImgToHistService;

namespace Robotics.ImgToHistService
{
    /// <summary>
    /// ImgToHistService contract class
    /// </summary>
    public sealed class Contract
    {
        /// <summary>
        /// DSS contract identifer for ImgToHistService
        /// </summary>
        [DataMember]
        public const string Identifier = "http://schemas.tempuri.org/2010/08/imgtohistservice.html";
    }

    /// <summary>
    /// ImgToHistService state
    /// </summary>
    [DataContract]
    public class ImgToHistServiceState
    {
        /// <summary>
        /// Histogram Dimensions
        /// </summary>
        [DataMember]
        [Description("Specifies the number of histogram dimensions.")]
        public int Dims;

        /// <summary>
        /// Histogram Bin Sizes
        /// </summary>
        [DataMember]
        [Description("Specifies the array for bin sizes.")]
        public int[] BinSizes;

        /// <summary>
        /// Histogram Bin Ranges
        /// </summary>
        [DataMember]
        [Description("Specifies the array for upper and lower limits of bins.")]
        public RangeF[] Ranges;

    }

    /// <summary>
    /// ImgToHistService main operations port
    /// </summary>
    [ServicePort]
    public class ImgToHistServiceOperations : PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, Subscribe, CalcHistFromImage, NotifyHistCalculation>
    {
    }

    /// <summary>
    /// ImgToHistService get operation
    /// </summary>
    public class Get : Get<GetRequestType, PortSet<ImgToHistServiceState, Fault>>
    {
        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        public Get()
        {
        }

        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        /// <param name="body">the request message body</param>
        public Get(GetRequestType body)
            : base(body)
        {
        }

        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        /// <param name="body">the request message body</param>
        /// <param name="responsePort">the response port for the request</param>
        public Get(GetRequestType body, PortSet<ImgToHistServiceState, Fault> responsePort)
            : base(body, responsePort)
        {
        }
    }

    /// <summary>
    /// Histogram Calculation operation
    /// </summary>
    public class CalcHistFromImage : Update<CalcHistFromImageRequest, PortSet<DefaultUpdateResponseType, Fault>>
    {
        public CalcHistFromImage()
        {
        }

        /// <summary>
        /// Constructor with CalcHistFromImageRequest
        /// </summary>
        public CalcHistFromImage(CalcHistFromImageRequest body)
            : base(body)
        {
        }
    }

    /// <summary>
    /// Calculate Histogram From Image Request Type
    /// </summary>
    [DataContract]
    [DataMemberConstructor]
    public class CalcHistFromImageRequest
    {
        [DataMember, DataMemberConstructor]
        [Description("Data for Input Image")]
        public byte[,,] ImageForHist;

        /// <summary>
        /// Constructor
        /// </summary>
        public CalcHistFromImageRequest()
        {
        }
        /// <summary>
        /// Constructor with Image Data Request (byte[,,])
        /// </summary>
        public CalcHistFromImageRequest(byte[,,] request)
        {
            ImageForHist = request;
        }
    }

    /// <summary>
    /// Histogram Calculation Notification Operation
    /// </summary>
    [DisplayName("CalculatedHistogram")]
    [Description("Indicates that a histogram has been calculated.")]
    public class NotifyHistCalculation : Update<HistResult, PortSet<DefaultUpdateResponseType, Fault>>
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public NotifyHistCalculation()
        {
        }

        /// <summary>
        /// Constructor with HistResult
        /// </summary>
        public NotifyHistCalculation(HistResult body)
            : base(body)
        {
        }
    }

    /// <summary>
    /// Histogram Calculation Result
    /// </summary>
    [DataContract]
    public class HistResult
    {
        /// <summary>
        /// Histogram Result
        /// </summary>
        [DataMember]
        [Description("The resulting histogram")]
        public MCvHistogram HistCalculated;
        
        /// <summary>
        /// Constructor
        /// </summary>
        public HistResult()
        {
        }
        /// <summary>
        /// Constructor with ImageHist as Result
        /// </summary>
        public HistResult(MCvHistogram result)
        {
            HistCalculated = result;
        }
    }

    /// <summary>
    /// ImgToHistService subscribe operation
    /// </summary>
    public class Subscribe : Subscribe<SubscribeRequestType, PortSet<SubscribeResponseType, Fault>>
    {
        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        public Subscribe()
        {
        }

        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        /// <param name="body">the request message body</param>
        public Subscribe(SubscribeRequestType body)
            : base(body)
        {
        }

        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        /// <param name="body">the request message body</param>
        /// <param name="responsePort">the response port for the request</param>
        public Subscribe(SubscribeRequestType body, PortSet<SubscribeResponseType, Fault> responsePort)
            : base(body, responsePort)
        {
        }
    }
}


